package cn.change.basic.service.impl;
import cn.change.basic.contants.BaseConstants;
import cn.change.basic.dto.RegisterDto;
import cn.change.basic.exception.BusinssException;
import cn.change.basic.service.VerifyCodeService;
import cn.change.basic.util.StrUtils;
import cn.change.basic.util.VerifyCodeUtils;
import cn.change.user.domain.User;
import cn.change.user.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.concurrent.TimeUnit;

@Service()
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Override
    public String graph(String key) {
       if (!StringUtils.hasLength(key)){
           throw new BusinssException("系统错误，稍后重试！！");
       }
        String code = StrUtils.getComplexRandomString(4);
        redisTemplate.opsForValue().set(
               key,
               code,
               5,
               TimeUnit.MINUTES);
               return VerifyCodeUtils.VerifyCode(104,38,code);
    }

    @Override
    public void smsCode(RegisterDto dto) {
        String type = dto.getType();
        if ("register".equals(type)){
            sendRegisterCode(dto);
        }else {
            sendBinderCode(dto);
        }
    }
    private void sendSmsCode(String businessKey){
        /*校验验证码是否已经发送过*/
        String smsCodeKey = businessKey;
        //3.1 根据手机号拼接业务键，从redis获取短信验证码 key  register:159824985856
        Object smsCodeTmp = redisTemplate.opsForValue().get(smsCodeKey);
        String smsCode = "";
        //4.生成验证码
        if(smsCodeTmp != null){
            //3.1.2 获取到了，判断是否过了重发时间1分钟 value 9527:465468426546521
            Long oldTime = Long.valueOf(smsCodeTmp.toString().split(":")[1]);
            if(System.currentTimeMillis()-oldTime <= 1*60*1000){
                //。小于一分钟，报错：请勿重复获取验证码
                throw new BusinssException("使劲骂！！！！  ");
            }
            //。大于一分钟，使用原来的验证码，刷新过期时间
            smsCode = smsCodeTmp.toString().split(":")[0];
        }else{
            //3.1.1 获取不到 说明已经过期，直接生成新的验证码
            smsCode = StrUtils.getComplexRandomString(4);
        }
        //5.保存reids 设置过期时间3分钟
        String smsCodeValue = smsCode + ":" + System.currentTimeMillis();
        redisTemplate.opsForValue().set(
                smsCodeKey,
                smsCodeValue,
                3,
                TimeUnit.MINUTES
        );
        //6.发送短信验证码
        //SmsUtils.sendMsg(phone,"亲，您的验证码是："+smsCode+"。请在3分钟内使用！！");
        System.out.println("亲，您的验证码是：" + smsCode + "。请在3分钟内使用！！");
    }

    /**
     * 发送绑定验证码
     * @param dto
     */
    private void sendBinderCode(RegisterDto dto) {
        String businessKey = BaseConstants.VerifyCodeConstants.BUSINESS_BINDER_PREFIX+dto.getPhone();
        sendSmsCode(businessKey);
    }

    /**
     * 发送注册验证码
     */
    private void sendRegisterCode(RegisterDto dto) {
        String phone = dto.getPhone();
        String imageCodeKey = dto.getImageCodeKey();
        String imageCodeValue = dto.getImageCodeValue();
        String type = dto.getType();
        //1.校验参数
        //。空校验
        if(StringUtils.isEmpty(phone)
                || StringUtils.isEmpty(imageCodeKey)
                || StringUtils.isEmpty(imageCodeValue)){
            throw new BusinssException("参数不能为空！！！");
        }
        //。校验手机号是否已经被注册
        User user = userMapper.loadByPhone(phone);
        if(user != null){
            throw new BusinssException("用户已经存在，请直接登录！！");
        }
        //        2.图形验证码校验，根据imageCodeKey 从redis获取图形验证码
        Object imageValueTmp = redisTemplate.opsForValue().get(imageCodeKey);
        //2.1 没有拿到 图形验证码失效，报错
        if(imageValueTmp == null){
            throw new BusinssException("图形验证码已失效，请重新获取！！");
        }
        //2.2 拿到了，判断输入的图形验证码是否正确 不要区分大小写
        if(!imageValueTmp.toString().equalsIgnoreCase(imageCodeValue)){
            throw new BusinssException("请输入正确的图形验证码！！");
        }
        String businessKey = BaseConstants.VerifyCodeConstants.BUSINESS_REGISTER_PREFIX+phone;
        sendSmsCode(businessKey);
    }

}
